﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace UnitTest
{
    public static class 超时停止任务
    {
        public static async void Go()
        {
            TimeSpan timeout = TimeSpan.FromSeconds(6);//超时时间
            int maxRetryCount = 2;//最大重试次数
            CancellationTokenSource cts = new CancellationTokenSource();
            bool isSuccess = false;
            string result = string.Empty;
            //1.超时取消任务 无返回值
            //isSuccess = await TaskExtensions.TimeoutCancelAsync((cts) => DoActionNoResult(cts), timeout, cts);

            //1.超时取消任务 无返回值
            //(isSuccess, result) = await TaskExtensions.TimeoutCancelAsync((cts) => DoActionWithResult(cts), timeout, cts);

            //3.超时取消并重试任务 无返回值
            //isSuccess = await TaskExtensions.TimeoutRetryAsync((cts) => DoActionNoResult(cts), timeout, maxRetryCount, cts);

            //4.超时取消并重试任务 带返回值任务
            (isSuccess, result) = await TaskExtensions.TimeoutRetryAsync((cts) => DoActionWithResult(cts), timeout, maxRetryCount, cts);
            
            if(isSuccess) 
            {
                Console.WriteLine("任务执行成功，结果：" + result);
            }
            else
            {
                Console.WriteLine("任务执行失败！");
            }
            Console.ReadLine();
        }

        public static async Task DoActionNoResult(CancellationTokenSource cts)
        {
            await Task.Delay(200);
            for (int i = 1; i <= 5; i++)
            {
                if (cts.IsCancellationRequested)//在业务任务每个耗时的操作开始之前判断取消令牌是否已取消
                    return;
                Console.WriteLine($"num:{i}");
                await Task.Delay(1000);//模拟业务操作，耗时任务。
            }
        }

        public static async Task<string> DoActionWithResult(CancellationTokenSource cts)
        {
            await Task.Delay(200);
            for (int i = 1; i <= 5; i++)
            {
                if (cts.IsCancellationRequested)//在业务任务每个耗时的操作开始之前判断取消令牌是否已取消
                    return "";
                Console.WriteLine($"num:{i}");
                await Task.Delay(1000);//模拟业务操作，耗时任务。
            }
            return "666";
        }
    }
}
